
from flask import request
from utils.randomUtils import generate_random_token, generate_random_by_time
import threading
from .baseGraphNode import  *
from .httpGraphNode import HttpGraphNode
from ..execute.baseExeHis import BaseExeHis
from .sessionInfo import SessionInfo
from collections import defaultdict
from eventlet.semaphore import Semaphore
import uuid

class HttpImageInGraphNode(BaseGraphNode):
    def __init__(self, id:str, data:dict, graphNodeManager, random_key:str):
        super().__init__(id, data, graphNodeManager, random_key)
        self.route = data['data']['route']
        if self.graphNodeManager.http_node is not None:
            self.full_url = self.graphNodeManager.http_node.full_url
        else:
            self.graphNodeManager.http_node = HttpGraphNode(generate_random_by_time(), self.data, self.graphNodeManager, self.random_key)
            self.full_url = self.graphNodeManager.http_node.full_url
        self._ws_token = self.full_url
        self.running = False
        self.session_locks = defaultdict(Semaphore)  # 每个session_id独立锁
        self.session_id_2_running_id = {}

    def execute(self, session_info: SessionInfo=None, exe_his: BaseExeHis=None, **kwargs):
        if (not self.running):
            if self.route in self.graphNodeManager.project.onlineRoutes:
                self.graphNodeManager.project.onlineRoutes.pop(self.route)
            self.running = True
            
            socketio_instance = self.graphNodeManager.http_node.get_socketio_instance()
            route = self.route
            full_url = self.full_url

            @socketio_instance.on(route, namespace=full_url)
            def handle_message(msg):
                if 'data' not in msg:
                    return
                msgdata = msg['data']# image's base64 code string 
                id = msg.get('id', None)
                if id is None:
                    print(f'{self.name} handle_message id is None')
                    return
                
                session_info = self.graphNodeManager.get_session_info(id, socketio_instance, request.sid, self.full_url) 
                with session_info.out_write_lock:
                    self.session_id_2_running_id[session_info.id]=str(uuid.uuid4()).replace('-', '')[:16]
                    if session_info.out.get(self.id,None) is None: session_info.out[self.id] = {}
                    if 'image' not in session_info.out[self.id] : session_info.out[self.id]['image'] = []
                    session_info.out[self.id]['image'].append(msgdata) # image_url
                self.executed_num += 1
                exe_his = self.get_new_exe_his(session_info.id)
                exe_his.update_content("Image Uploaded")
                exe_his.done()
                self.flow_next(session_info, trigger=self, running_id=self.session_id_2_running_id[session_info.id], type='image', role='user')

            
            self.graphNodeManager.project.addOnlineRoute(self.route, 'image', self.name)
            print(f'WebSocket app created and listening for Image, namespace: {self.full_url}')

    
